<?php

namespace App\Service\OpenShop\Feishu;

use App\Models\Common\CityResidencePriceModel;
use App\Models\Common\CityTerritorialBoundaryModel;
use App\Models\Common\ConfigModel;
use App\Models\Common\MapNationalBrandShopModel;
use App\Models\Common\MapNationalIndustrialParkModel;
use App\Models\Common\MapNationalUniversitiesModel;
use App\Models\OpenShop\Common\SiteLocationMallModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationModel;
use App\Remote\Rms\RmsShopRemote;
use App\Service\OpenShop\SiteLocation\GuanyuanDataService;
use Ballen\Distical\Calculator as DistanceCalculator;
use Ballen\Distical\Entities\LatLong;
use Illuminate\Support\Facades\Cache;
use Overtrue\Pinyin\Pinyin;

class MapService extends BaseService
{

    const REDIS_TAG_WANGGUI    = 'WANGGUI';

    public static function getMapData(): array
    {
        $data = Cache::get('tiger:openShop:map:wangguiMapData');
        if (null === $data) {
            \App\Service\BaseService::throwErr('数据获取失败, 请稍后再试');
        } else {
            return $data;
        }
    }

    public static function mapRank(): array
    {
        return Cache::remember('tiger:openShop:map:mapRank', 600, function () {
            try {
                $res = GuanyuanDataService::districtVolume();
            } catch (\Exception $exception) {
                $res = [];
            }
            $cityData = $districtData  = $provinceData = [];
            $provinceRankData = [
                'capacityRank'          => 0,//容量
                'businessShopNumRank'   => 0,//累计在营门店数
                'siteShopNumRank'       => 0,//选址中门店数
                'prepareShopNumRank'    => 0,//筹备中门店数
                'remainingPointNumRank' => 0,//剩余点位
                'shopNumRank'           => 0,//门店总数
            ];
            $cityRankData     = [
                'capacityRank'          => 0,//容量
                'businessShopNumRank'   => 0,//累计在营门店数
                'siteShopNumRank'       => 0,//选址中门店数
                'prepareShopNumRank'    => 0,//筹备中门店数
                'remainingPointNumRank' => 0,//剩余点位
                'shopNumRank'           => 0,//门店总数
            ];
            $districtRankData     = [
                'capacityRank'          => 0,//容量
                'businessShopNumRank'   => 0,//累计在营门店数
                'siteShopNumRank'       => 0,//选址中门店数
                'prepareShopNumRank'    => 0,//筹备中门店数
                'remainingPointNumRank' => 0,//剩余点位
                'shopNumRank'           => 0,//门店总数
            ];
            foreach ($res as $v) {
                //省
                if (isset($provinceData[$v['省']])) {
                    $provinceData[$v['省']]['capacity']          = $provinceData[$v['省']]['capacity'] + $v['容量'];
                    $provinceData[$v['省']]['businessShopNum']   = $provinceData[$v['省']]['businessShopNum'] + $v['累计在营门店数'];
                    $provinceData[$v['省']]['siteShopNum']       = $provinceData[$v['省']]['siteShopNum'] + $v['选址中门店数'];
                    $provinceData[$v['省']]['prepareShopNum']    = $provinceData[$v['省']]['prepareShopNum'] + $v['筹备中门店数'];
                    $provinceData[$v['省']]['remainingPointNum'] = $provinceData[$v['省']]['remainingPointNum'] + $v['剩余点位'];
                    $provinceData[$v['省']]['shopNum']           = $provinceData[$v['省']]['shopNum'] + $v['累计在营门店数'] + $v['选址中门店数'] + $v['筹备中门店数'];//门店总数 = 营业中门店+选址中门店+筹备中门店
                } else {
                    $provinceData[$v['省']]['province']          = $v['省'];
                    $provinceData[$v['省']]['capacity']          = $v['容量'];
                    $provinceData[$v['省']]['businessShopNum']   = $v['累计在营门店数'];
                    $provinceData[$v['省']]['siteShopNum']       = $v['选址中门店数'];
                    $provinceData[$v['省']]['prepareShopNum']    = $v['筹备中门店数'];
                    $provinceData[$v['省']]['remainingPointNum'] = $v['剩余点位'];
                    $provinceData[$v['省']]['shopNum']           = $v['累计在营门店数'] + $v['选址中门店数'] + $v['筹备中门店数'];//门店总数 = 营业中门店+选址中门店+筹备中门店
                }
                //市
                if (isset($cityData[$v['市']])) {
                    $cityData[$v['市']]['capacity']          = $cityData[$v['市']]['capacity'] + $v['容量'];
                    $cityData[$v['市']]['businessShopNum']   = $cityData[$v['市']]['businessShopNum'] + $v['累计在营门店数'];
                    $cityData[$v['市']]['siteShopNum']       = $cityData[$v['市']]['siteShopNum'] + $v['选址中门店数'];
                    $cityData[$v['市']]['prepareShopNum']    = $cityData[$v['市']]['prepareShopNum'] + $v['筹备中门店数'];
                    $cityData[$v['市']]['remainingPointNum'] = $cityData[$v['市']]['remainingPointNum'] + $v['剩余点位'];
                    $cityData[$v['市']]['shopNum']           = $cityData[$v['市']]['shopNum'] + $v['累计在营门店数'] + $v['选址中门店数'] + $v['筹备中门店数'];//门店总数 = 营业中门店+选址中门店+筹备中门店
                } else {
                    $cityData[$v['市']]['province']          = $v['省'];
                    $cityData[$v['市']]['city']              = $v['市'];
                    $cityData[$v['市']]['capacity']          = $v['容量'];
                    $cityData[$v['市']]['businessShopNum']   = $v['累计在营门店数'];
                    $cityData[$v['市']]['siteShopNum']       = $v['选址中门店数'];
                    $cityData[$v['市']]['prepareShopNum']    = $v['筹备中门店数'];
                    $cityData[$v['市']]['remainingPointNum'] = $v['剩余点位'];
                    $cityData[$v['市']]['shopNum']           = $v['累计在营门店数'] + $v['选址中门店数'] + $v['筹备中门店数'];//门店总数 = 营业中门店+选址中门店+筹备中门店
                }
                //区
                if (isset($districtData[$v['区']])) {
                    $districtData[$v['区']]['capacity']          = $districtData[$v['区']]['capacity'] + $v['容量'];
                    $districtData[$v['区']]['businessShopNum']   = $districtData[$v['区']]['businessShopNum'] + $v['累计在营门店数'];
                    $districtData[$v['区']]['siteShopNum']       = $districtData[$v['区']]['siteShopNum'] + $v['选址中门店数'];
                    $districtData[$v['区']]['prepareShopNum']    = $districtData[$v['区']]['prepareShopNum'] + $v['筹备中门店数'];
                    $districtData[$v['区']]['remainingPointNum'] = $districtData[$v['区']]['remainingPointNum'] + $v['剩余点位'];
                    $districtData[$v['区']]['shopNum']           = $districtData[$v['区']]['shopNum'] + $v['累计在营门店数'] + $v['选址中门店数'] + $v['筹备中门店数'];//门店总数 = 营业中门店+选址中门店+筹备中门店
                } else {
                    $districtData[$v['区']]['province']          = $v['省'];
                    $districtData[$v['区']]['city']              = $v['市'];
                    $districtData[$v['区']]['district']          = $v['区'];
                    $districtData[$v['区']]['capacity']          = $v['容量'];
                    $districtData[$v['区']]['businessShopNum']   = $v['累计在营门店数'];
                    $districtData[$v['区']]['siteShopNum']       = $v['选址中门店数'];
                    $districtData[$v['区']]['prepareShopNum']    = $v['筹备中门店数'];
                    $districtData[$v['区']]['remainingPointNum'] = $v['剩余点位'];
                    $districtData[$v['区']]['shopNum']           = $v['累计在营门店数'] + $v['选址中门店数'] + $v['筹备中门店数'];//门店总数 = 营业中门店+选址中门店+筹备中门店
                }
            }
            if ($provinceData) {
                $provinceRankData = [
                    'capacityRank'          => self::dataDeal($provinceData, 'capacity', 0, 5),         //容量
                    'businessShopNumRank'   => self::dataDeal($provinceData, 'businessShopNum', 0, 5),  //累计在营门店数
                    'siteShopNumRank'       => self::dataDeal($provinceData, 'siteShopNum', 0, 5),      //选址中门店数
                    'prepareShopNumRank'    => self::dataDeal($provinceData, 'prepareShopNum', 0, 5),   //筹备中门店数
                    'remainingPointNumRank' => self::dataDeal($provinceData, 'remainingPointNum', 0, 5),//剩余点位
                    'shopNumRank'           => self::dataDeal($provinceData, 'shopNum', 0, 5),          //门店总数
                ];
            }

            if ($cityData) {
                $cityRankData = [
                    'capacityRank'          => self::dataDeal($cityData, 'capacity', 0, 5),         //容量
                    'businessShopNumRank'   => self::dataDeal($cityData, 'businessShopNum', 0, 5),  //累计在营门店数
                    'siteShopNumRank'       => self::dataDeal($cityData, 'siteShopNum', 0, 5),      //选址中门店数
                    'prepareShopNumRank'    => self::dataDeal($cityData, 'prepareShopNum', 0, 5),   //筹备中门店数
                    'remainingPointNumRank' => self::dataDeal($cityData, 'remainingPointNum', 0, 5),//剩余点位
                    'shopNumRank'           => self::dataDeal($cityData, 'shopNum', 0, 5),          //门店总数
                ];
            }

            if ($districtData) {
                $districtRankData = [
                    'capacityRank'          => self::dataDeal($districtData, 'capacity', 0, 5),         //容量
                    'businessShopNumRank'   => self::dataDeal($districtData, 'businessShopNum', 0, 5),  //累计在营门店数
                    'siteShopNumRank'       => self::dataDeal($districtData, 'siteShopNum', 0, 5),      //选址中门店数
                    'prepareShopNumRank'    => self::dataDeal($districtData, 'prepareShopNum', 0, 5),   //筹备中门店数
                    'remainingPointNumRank' => self::dataDeal($districtData, 'remainingPointNum', 0, 5),//剩余点位
                    'shopNumRank'           => self::dataDeal($districtData, 'shopNum', 0, 5),          //门店总数
                ];
            }
            return ['provinceRankData' => $provinceRankData, 'cityRankData' => $cityRankData, 'districtRankData' => $districtRankData];
        });
    }

    /**
     * 数组处理+排序
     * @param array $data
     * @param string $key
     * @param int $flagRate
     * @param int $flagCount
     * @return array
     */
    public static function dataDeal(array $data, $key = 'businessShopNum', $flagRate = 1, $flagCount = 0): array
    {
        if (!$data || !is_array($data)) {
            return [];
        }
        if ($flagRate) {
            foreach ($data as &$v) {
                $v['penetrationRate'] = $v['capacity'] > 0 && $v['shopNum'] > 0 ?
                    round($v['shopNum'] * 100 / $v['capacity'], 2) . "%" : 0;//渗透率 = 门店总数/网规容量
            }
        }
        $vol = array_column($data, $key);//用在营门店数排序
        array_multisort($vol, SORT_DESC, $data);
        if ($flagCount > 0) {
            $data = array_slice($data, 0, $flagCount);//取前面几个
            $data = array_values($data);
        }
        return $data;
    }

    /**
     * 全国省市区范围经纬度
     * @param string $pAdcode
     * @param string $level
     * @return array
     */
    public static function mapRange($pAdcode = '', $level = ''): array
    {
        return Cache::rememberForever('tiger:openShop:map:mapRange', function () use ($level, $pAdcode) {
            if ($level == '') {
                $level = CityTerritorialBoundaryModel::LEVEL_PROVINCE;
            }
            $pData = CityTerritorialBoundaryModel::getData($pAdcode, $level);//省
            if ($pData) {
                foreach ($pData as $k => $v) {
                    $level = CityTerritorialBoundaryModel::LEVEL_CITY;
                    $city  = CityTerritorialBoundaryModel::getData($v['adcode'], $level);//市
                    if ($city) {
                        foreach ($city as $kk => $vv) {
                            $level                 = CityTerritorialBoundaryModel::LEVEL_DISTRICT;
                            $city[$kk]['district'] = CityTerritorialBoundaryModel::getData($vv['adcode'], $level);//区
                        }
                    }
                    $pData[$k]['city'] = $city;
                }
            }
            return $pData;
        });
    }


    /**
     * 单个店铺点位详细通过shopCode
     * @param $shopCode
     * @return array[]
     */
    public static function mapDetail($shopCode): array
    {
        return Cache::remember('tiger:openShop:map:mapDetail'.$shopCode, 600, function () use ($shopCode) {
            $shopInfo = RmsShopRemote::getShopFieldsByCodes([$shopCode])['shopList'][0] ?? [];
            if ($shopInfo) {
                $shopInfo = [
                    "id"            => $shopInfo['id'],
                    "shopCode"      => $shopInfo['shopCode'],
                    "name"          => $shopInfo['name'],
                    "shopMobile"    => $shopInfo['shopMobile'],
                    "shopContact"   => $shopInfo['shopContact'],
                    "imageUrl"      => $shopInfo['imageUrl'],
                    "address"       => $shopInfo['address'],
                    "addressPrefix" => $shopInfo['addressPrefix'],
                    "province"      => $shopInfo['province'],
                    "city"          => $shopInfo['city'],
                    "district"      => $shopInfo['district'],
                    "lng"           => $shopInfo['lng'],
                    "lat"           => $shopInfo['lat'],
                    "branch"        => $shopInfo['branch'],
                ];
            }
            if ((config('app.env') == 'qa' || config('app.env') == 'dev') && (!$shopInfo || !$shopInfo['lat'] || !$shopInfo['lng'])) {
                $shopInfo['lat'] = 31.026158;
                $shopInfo['lng'] = 121.414887;
                $shopInfo['shopCode'] = $shopCode;
            }
            $distanceNum = 3;//3km
            //附近3km的夸父门店
            $nearByShop = GuanyuanDataService::nearbyShop($shopInfo['lat'], $shopInfo['lng'], $distanceNum, '', $shopInfo['shopCode'] ?? '');
            //附近3km的预占点位
            $placeholderShop = self::getPlaceholderList($shopInfo['lat'], $shopInfo['lng'], $distanceNum);
            //附近3km内商场信息
            $mallData = self::getMallData($shopInfo['lat'], $shopInfo['lng'], $distanceNum);
            //附近3km内小区信息
            $residenceData = self::getResidenceData($shopInfo['lat'], $shopInfo['lng'], $distanceNum);
            //附近3km产业园区信息
            $nationalIndustrialParkData = self::getNationalIndustrialParkData($shopInfo['lat'], $shopInfo['lng'], $distanceNum);
            //附近3km高校
            $nationalUniversitiesData = self::getNationalUniversitiesData($shopInfo['lat'], $shopInfo['lng'], $distanceNum);
            //附近3km内关联品牌数据信息
            $getOtherBrandShopData = self::getOtherBrandShopData($shopInfo['lat'], $shopInfo['lng'], $distanceNum);
            return [
                'shopInfo'                   => $shopInfo,
                'nearByShop'                 => $nearByShop,
                'placeholderShop'            => $placeholderShop,
                'mallData'                   => $mallData,
                'residenceData'              => $residenceData,
                'nationalIndustrialParkData' => $nationalIndustrialParkData,
                'nationalUniversitiesData'   => $nationalUniversitiesData,
                'otherBrandShopData'         => $getOtherBrandShopData,
            ];
        });
    }


    /**
     * 附近3km的预占点位
     * @param $lat
     * @param $lng
     * @param $distanceNum
     * @return array
     */
    public static function getPlaceholderList($lat, $lng, $distanceNum): array
    {
        $placeholderList = OpenShopSiteLocationModel::query()
            ->where('source', OpenShopSiteLocationModel::SOURCE_PLACEHOLDER)
            ->where('placeholderTime', '>', time())
            ->where('siteStatus', OpenShopSiteLocationModel::SITE_STATUS_4)
            ->get();
        $placeholderShop = [];
        foreach ($placeholderList as $k => $placeholder) {
            try {
                $distance = (new DistanceCalculator(
                    new LatLong($lat, $lng),
                    new LatLong($placeholder->latitude, $placeholder->longitude)
                ))->get()->asKilometres();
            } catch (\Exception $e) {
                $distance = 0;
            }
            if ($distance <= $distanceNum) {
                $placeholderShop[] = [
                    'shopName'        => $placeholder->shopName,
                    'siteAddress'     => $placeholder->siteAddress,
                    'placeholderTime' => formatDate($placeholder->placeholderTime),
                    'longitude'       => $placeholder->longitude,
                    'latitude'        => $placeholder->latitude,
                    'distance'        => $distance,
                    'distanceText'    => GuanyuanDataService::distanceText($distance),
                ];
            }
        }
        if ($placeholderShop) {
            $placeholderShop = collect($placeholderShop)->sortBy('distance')->first();
        }
        return $placeholderShop;
    }


    /**
     * 附近3km内商场信息
     * @param $lat
     * @param $lng
     * @param $distanceNum
     * @return array
     */
    public static function getMallData($lat, $lng, $distanceNum): array
    {
        $mallData = [];
        SiteLocationMallModel::query()
            ->selectRaw(
                "mallId,mallName,star,address, st_distance_sphere (
        point ( lng, lat ),
        point ( {$lng}, {$lat} )) AS distance"
            )
            ->orderBy('distance')
            ->limit(300)
            ->get()
            ->each(
                function (SiteLocationMallModel $siteLocationMallModel) use ($distanceNum, &$mallData) {
                    if ($siteLocationMallModel->distance <= $distanceNum * 1000) {
                        if (count($mallData) >= 100) {
                            return;
                        }
                        $mallData[] = [
                            'mallId'       => $siteLocationMallModel->mallId,
                            'mallName'     => $siteLocationMallModel->mallName,
                            'star'         => $siteLocationMallModel->star,
                            'address'      => $siteLocationMallModel->address,
                            'lng'          => $siteLocationMallModel->lng,
                            'lat'          => $siteLocationMallModel->lat,
                            'distance'     => $siteLocationMallModel->distance,
                            'distanceText' => GuanyuanDataService::distanceText(round($siteLocationMallModel->distance / 1000, 5)),
                        ];
                    }
                }
            );
        return $mallData;
    }

    /**
     * 附近3km内小区信息
     * @param $lat
     * @param $lng
     * @param $distanceNum
     * @return array
     */
    public static function getResidenceData($lat, $lng, $distanceNum): array
    {
        $residenceData = [];
        CityResidencePriceModel::query()
            ->selectRaw(
                "id,name,price,centerLongitude,centerLatitude, st_distance_sphere (
        point ( centerLongitude, centerLatitude ),
        point ( {$lng}, {$lat} )) AS distance"
            )
            ->orderBy('distance')
            ->limit(1000)
            ->get()
            ->each(
                function (CityResidencePriceModel $cityResidencePriceModel) use ($distanceNum, &$residenceData) {
                    if ($cityResidencePriceModel->distance <= $distanceNum * 1000) {
                        if (count($residenceData) >= 300) {
                            return;
                        }
                        $residenceData[] = [
                            'id'           => $cityResidencePriceModel->id,
                            'name'         => $cityResidencePriceModel->name,
                            'price'        => $cityResidencePriceModel->price,
                            'lng'          => $cityResidencePriceModel->centerLongitude,
                            'lat'          => $cityResidencePriceModel->centerLatitude,
                            'distance'     => $cityResidencePriceModel->distance,
                            'distanceText' => GuanyuanDataService::distanceText(round($cityResidencePriceModel->distance / 1000, 5)),
                        ];
                    }
                }
            );
        return $residenceData;
    }

    /**
     * 附近3km产业园区信息
     * @param $lat
     * @param $lng
     * @param $distanceNum
     * @return array
     */
    public static function getNationalIndustrialParkData($lat, $lng, $distanceNum): array
    {

        $nationalIndustrialParkData = [];
        MapNationalIndustrialParkModel::query()
            ->selectRaw(
                "id,name,province,city,district,lon,lat, st_distance_sphere (
        point ( lon, lat ),
        point ( {$lng}, {$lat} )) AS distance"
            )
            ->orderBy('distance')
            ->limit(1000)
            ->get()
            ->each(
                function (MapNationalIndustrialParkModel $mapNationalIndustrialParkModel) use ($distanceNum, &$nationalIndustrialParkData) {
                    if ($mapNationalIndustrialParkModel->distance <= $distanceNum * 1000) {
                        if (count($nationalIndustrialParkData) >= 100) {
                            return;
                        }
                        $nationalIndustrialParkData[] = [
                            'id'           => $mapNationalIndustrialParkModel->id,
                            'name'         => $mapNationalIndustrialParkModel->name,
                            'province'     => $mapNationalIndustrialParkModel->province,
                            'city'         => $mapNationalIndustrialParkModel->city,
                            'district'     => $mapNationalIndustrialParkModel->district,
                            'lng'          => $mapNationalIndustrialParkModel->lon,
                            'lat'          => $mapNationalIndustrialParkModel->lat,
                            'distance'     => $mapNationalIndustrialParkModel->distance,
                            'distanceText' => GuanyuanDataService::distanceText(round($mapNationalIndustrialParkModel->distance / 1000, 5)),
                        ];
                    }
                }
            );
        return $nationalIndustrialParkData;
    }

    /**
     * 附近3km高校
     * @param $lat
     * @param $lng
     * @param $distanceNum
     * @return array
     */
    public static function getNationalUniversitiesData($lat, $lng, $distanceNum): array
    {

        $nationalUniversitiesData = [];
        MapNationalUniversitiesModel::query()
            ->selectRaw(
                "id,name,province,city,district,startData,project985,project211,doubleFirstClass,strongBasis,space,lon,lat, st_distance_sphere (
        point ( lon, lat ),
        point ( {$lng}, {$lat} )) AS distance"
            )
            ->orderBy('distance')
            ->limit(1000)
            ->get()
            ->each(
                function (MapNationalUniversitiesModel $mapNationalUniversitiesModel) use ($distanceNum, &$nationalUniversitiesData) {
                    if ($mapNationalUniversitiesModel->distance <= $distanceNum * 1000) {
                        if (count($nationalUniversitiesData) >= 100) {
                            return;
                        }
                        $nationalUniversitiesData[] = [
                            'id'           => $mapNationalUniversitiesModel->id,
                            'name'         => $mapNationalUniversitiesModel->name,
                            'province'     => $mapNationalUniversitiesModel->province,
                            'city'         => $mapNationalUniversitiesModel->city,
                            'district'     => $mapNationalUniversitiesModel->district,
                            'lng'          => $mapNationalUniversitiesModel->lon,
                            'lat'          => $mapNationalUniversitiesModel->lat,
                            'distance'     => $mapNationalUniversitiesModel->distance,
                            'distanceText' => GuanyuanDataService::distanceText(round($mapNationalUniversitiesModel->distance / 1000, 5)),
                        ];
                    }
                }
            );
        return $nationalUniversitiesData;
    }


    /**
     * 附近3km品牌数据信息
     * @param $lat
     * @param $lng
     * @param $distanceNum
     * @return array
     */
    public static function getOtherBrandShopData($lat, $lng, $distanceNum): array
    {
        $getOtherBrandShopData = [];
        MapNationalBrandShopModel::query()
            ->selectRaw(
                "id,name,brand,province,city,district,openingTime,star,lon,lat, st_distance_sphere (
        point ( lon, lat ),
        point ( {$lng}, {$lat} )) AS distance"
            )
            ->orderBy('distance')
            ->limit(1000)
            ->get()
            ->each(function (MapNationalBrandShopModel $mapNationalBrandShopModel) use ($distanceNum, &$getOtherBrandShopData) {
                    if ($mapNationalBrandShopModel->distance <= $distanceNum * 1000) {
                        if (count($getOtherBrandShopData) >= 1000) {
                            return;
                        }
                        $getOtherBrandShopData[] = [
                            'id'           => $mapNationalBrandShopModel->id,
                            'name'         => $mapNationalBrandShopModel->name,
                            'province'     => $mapNationalBrandShopModel->province,
                            'city'         => $mapNationalBrandShopModel->city,
                            'district'     => $mapNationalBrandShopModel->district,
                            'brand'        => $mapNationalBrandShopModel->brand,
                            'star'         => $mapNationalBrandShopModel->star,
                            'lng'          => $mapNationalBrandShopModel->lon,
                            'lat'          => $mapNationalBrandShopModel->lat,
                            'distance'     => $mapNationalBrandShopModel->distance,
                            'distanceText' => GuanyuanDataService::distanceText(round($mapNationalBrandShopModel->distance / 1000, 5)),
                        ];
                    }
                }
            );
        return $getOtherBrandShopData;
    }

    /**
     * 城市内数据集列表
     * @param $city
     * @param $district
     * @param string $province
     * @param int $source  根据来源获取返回类型
     * @return array
     */
    public static function mapDataList($city, $district, string $province = ''): array
    {
        //        return Cache::remember('tiger:openShop:map:mapDataList:' . $city . $district, 600, function () use ($city, $district) {
       $recommendArea = $otherBrandShopNewData = [];

        list($shopOpen, $shopPause, $shopPreparatory, $shopSite, $shopPreSite) =
            Cache::store('array')
                 ->remember('MapService_mapDataList', 3600, function () use ($city, $district, $province) {

                     $shopOpen = $shopPause = $shopPreparatory = $shopSite = $shopPreSite = [];

                     try {
                         $guanYuanShopList = GuanyuanDataService::newShopList();
                     } catch (\Exception $exception) {
                         $guanYuanShopList = [];
                     }
                     if ($guanYuanShopList) {
                         foreach ($guanYuanShopList as $v) {

                             if (!$v['门店纬度'] || !$v['门店经度']) {
                                 continue;
                             }

                             if ($province && $v['门店所在省'] != $province) {
                                 continue;
                             }
                             if ($city && $v['门店所在市'] != $city) {
                                 continue;
                             }
                             if ($district && $v['区/县'] != $district) {
                                 continue;
                             }
                             $data = [
                                 'name'        => $v['门店名称'],
                                 'shopCode'    => $v['铺位号'],
                                 'status'      => $v['状态'],
                                 'province'    => $v['门店所在省'],
                                 'city'        => $v['门店所在市'],
                                 'district'    => $v['区/县'],
                                 'address'     => $v['店铺地址'],
                                 'openingTime' => $v['开业日期'],
                                 'lon'         => $v['门店经度'],
                                 'lat'         => $v['门店纬度'],
                             ];
                             switch ($v['状态']) {
                                 case '正常营业':
                                     $shopOpen[] = $data;
                                     break;
                                 case '暂停营业':
                                     $shopPause[] = $data;
                                     break;
                                 case '筹备中':
                                     $shopPreparatory[] = $data;
                                     break;
                                 case '选址中':
                                     $shopSite[] = $data;
                                     break;
                                 case '预占点位':
                                     $shopPreSite[] = $data;
                                     break;
                             }
                         }
                     }

                     return [$shopOpen, $shopPause, $shopPreparatory, $shopSite, $shopPreSite];
                 });

        //预占点位
        $shopPreSite = OpenShopSiteLocationModel::query()
            ->where('source', OpenShopSiteLocationModel::SOURCE_PLACEHOLDER)
            ->where('placeholderTime', '>', time())
            ->where('siteStatus', OpenShopSiteLocationModel::SITE_STATUS_4)
            ->when($province, function ($query) use ($province) {
                $province = mb_substr($province, 0, 2);
                $query->where('cityArea', 'like', "{$province}%");
            })
            ->when($city, function ($query) use ($city) {
                $query->where('cityArea', 'like', "{$city}%");
            })
            ->when($district, function ($query) use ($district) {
                $query->where('cityArea', 'like', "{$district}%");
            })
            ->select('longitude', 'latitude', 'shopName', 'siteAddress', 'placeholderTime')
            ->get()
            ->each(function (OpenShopSiteLocationModel $openShopSiteLocationModel) use (&$shopPreSite) {
                if ($openShopSiteLocationModel->longitude && $openShopSiteLocationModel->latitude) {
                    $shopPreSite[] = [
                        'shopName'        => $openShopSiteLocationModel->shopName,
                        'siteAddress'     => $openShopSiteLocationModel->siteAddress,
                        'placeholderTime' => formatDate($openShopSiteLocationModel->placeholderTime),
                        'lon'             => $openShopSiteLocationModel->longitude,
                        'lat'             => $openShopSiteLocationModel->latitude,
                    ];
                }
            }
            )
            ->toArray();

        //商场信息
        $mallData = [];
        SiteLocationMallModel::query()
            ->when($province, function ($query) use ($province) {
                $province = mb_substr($province, 0, 2);
                $query->where('province', 'like', "{$province}%");
            })
            ->when($city, function ($query) use ($city) {
                $query->where('city', str_replace('市', '', $city));
            })
            ->when($district, function ($query) use ($district) {
                //区一级 匹配前面的字段
                $district = str_replace('区', '', $district);
                $district = str_replace('县', '', $district);
                $district = str_replace('市', '', $district);
                $query->where('district', 'like', "{$district}%");
            })
            ->select(['mallId', 'mallName', 'star', 'address', 'lng', 'lat'])
            ->get()
            ->each(function (SiteLocationMallModel $siteLocationMallModel) use (&$mallData) {
                if ($siteLocationMallModel->lng && $siteLocationMallModel->lat) {
                    $mallData[] = $siteLocationMallModel->toArray();
                }
            });

        //小区信息
        $residenceData = [];
        CityResidencePriceModel::query()
            ->when($province, function ($query) use ($province) {
                $province = mb_substr($province, 0, 2);
                $query->where('province', 'like', "{$province}%");
            })
            ->when($city, function ($query) use ($city) {
                $query->where('city', $city);
            })
            ->when($district, function ($query) use ($district) {
                $query->where('district', $district);
            })
            ->select(['name', 'centerLongitude as lon', 'centerLatitude as lat', 'price'])
            ->get()
            ->each(function (CityResidencePriceModel $cityResidencePriceModel) use (&$residenceData) {
                if ($cityResidencePriceModel->lon && $cityResidencePriceModel->lat) {
                    $residenceData[] = $cityResidencePriceModel->toArray();
                }
            });


        //产业园区信息
        $nationalIndustrialParkData = [];
        MapNationalIndustrialParkModel::query()
            ->when($province, function ($query) use ($province) {
                $province = mb_substr($province, 0, 2);
                $query->where('province', 'like', "{$province}%");
            })
            ->when($city, function ($query) use ($city) {
                $query->where('city', $city);
            })
            ->when($district, function ($query) use ($district) {
                $query->where('district', $district);
            })
            ->select(['name', 'province', 'city', 'district', 'lon', 'lat'])
            ->get()
            ->each(function (MapNationalIndustrialParkModel $mapNationalIndustrialParkModel) use (&$nationalIndustrialParkData) {
                if ($mapNationalIndustrialParkModel->lon && $mapNationalIndustrialParkModel->lat) {
                    $nationalIndustrialParkData[] = $mapNationalIndustrialParkModel->toArray();
                }
            });

        //高校
        $nationalUniversitiesData = [];
        MapNationalUniversitiesModel::query()
            ->when($province, function ($query) use ($province) {
                $province = mb_substr($province, 0, 2);
                $query->where('province', 'like', "{$province}%");
            })
            ->when($city, function ($query) use ($city) {
                $query->where('city', $city);
            })
            ->when($district, function ($query) use ($district) {
                $query->where('district', $district);
            })
            ->select(['name', 'province', 'city', 'district', 'startData', 'project985', 'project211', 'doubleFirstClass', 'strongBasis', 'space', 'lon', 'lat'])
            ->get()
            ->each(function (MapNationalUniversitiesModel $mapNationalUniversitiesModel) use (&$nationalUniversitiesData) {
                if ($mapNationalUniversitiesModel->lon && $mapNationalUniversitiesModel->lat) {
                    $nationalUniversitiesData[] = $mapNationalUniversitiesModel->toArray();
                }
            });

        //关联品牌数据信息
        $otherBrandShopData = [];
        MapNationalBrandShopModel::query()
            ->when($province, function ($query) use ($province) {
                $province = mb_substr($province, 0, 2);
                $query->where('province', 'like', "{$province}%");
            })
            ->when($city, function ($query) use ($city) {
                $query->where('city', $city);
            })
            ->when($district, function ($query) use ($district) {
                $query->where('district', $district);
            })
            ->select(['name', 'brand', 'province', 'city', 'district', 'openingTime', 'star', 'lon', 'lat', 'address'])
            ->get()
            ->each(function (MapNationalBrandShopModel $mapNationalBrandShopModel) use (&$otherBrandShopData) {
                if ($mapNationalBrandShopModel->lon && $mapNationalBrandShopModel->lat) {
                    $otherBrandShopData[] = $mapNationalBrandShopModel->toArray();
                }
            });

        $py = (new Pinyin());

        $brandShopData = [];
        $pinyinData    = [];
        if (count($otherBrandShopData)) {
            foreach ($otherBrandShopData as $v) {
                $otherBrandShopNewData[$v['brand']][] = $v;
                if (isset($pinyinData[$v['brand']])) {
                    $brandKey = $pinyinData[$v['brand']];
                } else {
                    $brandKey                = Cache::store('array')->remember("pinyin:{$v['brand']}", 3600, function () use ($v, $py) {
                        return $py->permalink($v['brand'], '');
                    });
                    $pinyinData[$v['brand']] = $brandKey;
                }
                $brandShopData[$brandKey][] = $v;
            }
        }

        $res = [
            'shopOpen'                   => $shopOpen,
            'shopPause'                  => $shopPause,
            'shopPreparatory'            => $shopPreparatory,
            'shopSite'                   => $shopSite,
            'shopPreSite'                => $shopPreSite,
            'recommendArea'              => $recommendArea,
            'mallData'                   => $mallData,
            'residenceData'              => $residenceData,
            'nationalIndustrialParkData' => $nationalIndustrialParkData,
            'nationalUniversitiesData'   => $nationalUniversitiesData,
            'otherBrandShopData'         => $otherBrandShopNewData,
        ];

        return array_merge($res, $brandShopData);
        //        });
    }

    /**
     * 通过城市查询推荐区域
     * @param string $city
     * @return array
     */
    public static function mapRecommend(string $city): array
    {
        $mapRecommend = json_decode(
            ConfigModel::query()
                ->where('module', 'mapData')
                ->where('name', 'mapRecommend')
                ->value('value') ?? [], true
        );
        if (!$mapRecommend) {
            return [];
        }
        return $mapRecommend[$city] ? ['data' => $mapRecommend[$city]] : [];
    }

    /**
     * 获取不同品牌店铺信息
     * @param string $brand
     * @param int $flagRank
     * @return mixed
     */
    public static function getOtherBrandShop(string $brand, int $flagRank = 0): array
    {
        return Cache::rememberForever('tiger:openShop:map:getBrandShop:' . $brand, function () use ($flagRank, $brand) {
            $res = MapNationalBrandShopModel::query()
                ->where('brand', $brand)
                ->select(['name', 'address', 'brand', 'province', 'city', 'district', 'openingTime', 'star', 'lon', 'lat'])
                ->get()
                ->toArray();

            $total = $provinceData = $cityData = $data = [];
            if ($res) {
                foreach ($res as $v) {
                    //省
                    if (isset($provinceData[$v['province']])) {
                        $provinceData[$v['province']] += 1;
                    } else {
                        $provinceData[$v['province']] = 1;
                    }
                    //市
                    if (isset($cityData[$v['city']])) {
                        $cityData[$v['city']] += 1;
                    } else {
                        $cityData[$v['city']] = 1;
                    }
                    //区
                    if (isset($data[$v['province']][$v['city']][$v['district']])) {
                        $data[$v['province']][$v['city']][$v['district']] += 1;
                    } else {
                        $data[$v['province']][$v['city']][$v['district']] = 1;
                    }

                }
                $total        = [
                    'shopTotalNum'            => count($res),//门店总数
                    'provincePenetrationRate' => 0,//省级覆盖率
                    'provinceTotalNum'        => count($provinceData),//省数量
                    'cityPenetrationRate'     => 0,//城市覆盖率
                    'cityTotalNum'            => count($cityData),//城市数量
                ];
                arsort($provinceData);
                arsort($cityData);
                $cityData = array_slice($cityData, 0, 5);//取前面几个
            }
            if ($flagRank == 1) {//榜单
                return ['provinceRankData' => $provinceData, 'cityRankData' => $cityData];
            } else {
                return ['provinceData' => $provinceData, 'cityData' => $cityData, 'total' => $total];
            }
        });
    }

    /**
     * 获得省市区中心点
     * @return array
     */
    public static function mapCenterPoint(): array
    {
        //获得与地图一样的名字
        //$res = GuanyuanDataService::districtVolume();
        return Cache::rememberForever('tiger:openShop:map:wangguiMapCenterPoint', function () {
            return CityTerritorialBoundaryModel::query()
                ->whereIn('level', ['city', 'province'])
                ->select(['id', 'name', 'centerLongitude', 'centerLatitude'])
                ->get()
                ->toArray();
        });
    }
}
